//package com.info.zhiduoduo.core.service.payment.project;
//
//import com.alibaba.fastjson.JSON;
//import com.baomidou.mybatisplus.mapper.Condition;
//import com.info.zhiduoduo.common.configs.PayConfig;
//import com.info.zhiduoduo.common.configs.ZddUrlConfig;
//import com.info.zhiduoduo.common.constants.Constants;
//import com.info.zhiduoduo.common.constants.SmartResult;
//import com.info.zhiduoduo.common.constants.StatusMsg;
//import com.info.zhiduoduo.common.constants.company.CompanyAccountFlowAccountType;
//import com.info.zhiduoduo.common.constants.company.CompanyAccountFlowBizType;
//import com.info.zhiduoduo.common.constants.pay.DaysPayOrderState;
//import com.info.zhiduoduo.common.constants.pay.PayAccount;
//import com.info.zhiduoduo.common.constants.pay.PayPrefix;
//import com.info.zhiduoduo.common.exception.Asserts;
//import com.info.zhiduoduo.common.exception.RollbackException;
//import com.info.zhiduoduo.common.exception.SmartException;
//import com.info.zhiduoduo.common.utils.LogUtil;
//import com.info.zhiduoduo.common.utils.NumberUtil;
//import com.info.zhiduoduo.common.utils.RandomUtil;
//import com.info.zhiduoduo.core.dto.dayspay.DaysAgentPayFormBean;
//import com.info.zhiduoduo.core.dto.dayspay.DaysPayResDTO;
//import com.info.zhiduoduo.core.dto.dayspay.DaysQueryAgentPayFormBean;
//import com.info.zhiduoduo.core.dto.dayspay.DaysQueryPayResDTO;
//import com.info.zhiduoduo.core.service.common.BaseService;
//import com.info.zhiduoduo.core.service.payment.thirdpay.DaysPayService;
//import com.info.zhiduoduo.repository.entity.company.CompanyAccount;
//import com.info.zhiduoduo.repository.entity.company.CompanyAccountflow;
//import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceAccount;
//import com.info.zhiduoduo.repository.entity.foreign.ForeignInvoice;
//import com.info.zhiduoduo.repository.entity.foreign.ForeignProject;
//import com.info.zhiduoduo.repository.entity.foreign.ForeignTradeRecord;
//import com.info.zhiduoduo.repository.mapper.company.CompanyAccountMapper;
//import com.info.zhiduoduo.repository.mapper.foreign.ForeignProjectMapper;
//import com.info.zhiduoduo.repository.mapper.foreign.ForeignTradeRecordMapper;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.web.client.RestTemplate;
//
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.util.Arrays;
//import java.util.Date;
//import java.util.List;
//
//import javax.annotation.Resource;
//
//import lombok.extern.slf4j.Slf4j;
//
//@Slf4j
//@Service
//public class ForeignProjectPaymentService extends BaseService {
//
//	@Resource
//	ForeignProjectMapper foreignProjectMapper;
//	@Resource
//	ForeignTradeRecordMapper foreignTradeRecordMapper;
//	@Resource
//	CompanyAccountMapper companyAccountMapper;
//
//	@Autowired
//	DaysPayService daysPayService;
//
//	@Autowired
//	ZddUrlConfig zddUrlConfig;
//	@Autowired
//	PayConfig payConfig;
//
//	@Transactional
//	public SmartResult payProject(ForeignProject project) {
//		CrowdsourceAccount crowdsourceAccount = new CrowdsourceAccount().selectOne(Condition.create().eq("crowdsourceid", project.getCrowdsourceid()));
//		//非空校验
//		Asserts.notNull(crowdsourceAccount, StatusMsg.PERSON_NOT_EXISTS_ERROR);
//		Integer projectId = project.getProjectId();
//		//计算服务费和企业应付金额
//		calcProjectServiceCharge(project, NumberUtil.safeDouble(crowdsourceAccount.getServiceRate()));
//		// 检查金额是否足够, 并扣除应扣金额
//		CompanyAccount companyAccount = new CompanyAccount().selectOne(Condition.create().eq("compid", project.getCompid()));
//		Asserts.notNull(companyAccount, StatusMsg.MERCHANT_NOT_EXISTS_ERROR);
//		//检查企业金额并生成企业流水
//		deductCompanyBalanceForPublishProject(crowdsourceAccount, companyAccount, project);
//		//支付记录,检查是否已存在还未处理好的支付记录.如果有,那么需要等待
//		int recordProcessing = new ForeignTradeRecord().selectCount(Condition.create()
//				.eq("project_id", projectId)
//				.eq("business_type", Constants.KLT_PAY_BUSINESS_TYPE_USER_AMOUNT)
//				.in("tradestate", Arrays.asList(Constants.TRADE_CREATE, Constants.TRADE_IN_PROCESS)));
//		Asserts.equalZero(recordProcessing, StatusMsg.PAYMENT_PROCEEDING_ERROR);
//		//支付创建中,处理中和处理成功,表示不需要再新建了.直接返回
//		int recordSuccess = new ForeignTradeRecord().selectCount(
//				Condition.create().eq("project_id", projectId).eq("business_type", Constants.KLT_PAY_BUSINESS_TYPE_USER_AMOUNT).eq("tradestate", Constants.TRADE_SUCCESS));
//		Asserts.equalZero(recordSuccess, StatusMsg.PAYMENT_PROCEEDING_ERROR);
//		String purpose = project.getProjectName() + "-项目款";
//		if (purpose.length() > 16) {
//			purpose = purpose.substring(0, 16);
//		}
//		// 2020.6.6 根据项目的支付方式,确定商户号id:九歌统一账户或者企业自己的商户号
//		int payAccount;
//		// 使用九歌统一账户进行支付
//		payAccount = PayAccount.DAYS_ZHISHENG;
//		ForeignTradeRecord trade = new ForeignTradeRecord().setAcctname(crowdsourceAccount.getRealname())
//				.setBankname(project.getBankName())
//				.setAcctno(project.getAcctNo())
//				.setAccttype(1)
//				.setPurpose(purpose)
//				.setTradeamount(project.getAmount())
//				.setTradeno(RandomUtil.createRandomNo(PayPrefix.FP, ""))
//				.setTradetime(new Date())
//				.setTradetype(Constants.TRADE_TYPE_PAYMENT)
//				.setPayAccount(payAccount)
//				.setBusinessType(Constants.KLT_PAY_BUSINESS_TYPE_USER_AMOUNT)
//				.setProjectId(projectId)
//				.setIdtype(1)
//				.setTradestate(2)
//				.setUserid(project.getCrowdsourceid());
//		// 修改项目状态并插入支付记录
//		if (project.setPayState(2).updateById() && trade.insert()) {
//			System.out.println("---------新增流水成功---------");
//			// 2020.7.7 开联通系统维护,不能使用九歌商户号统一代付了.
//			// if (true) {
//			// 	throw SmartException.of(StatusMsg.StatusMsg_197);
//			// }
//			return doCallPayApi(trade);
//		}
//		return SmartResult.fail(StatusMsg.StatusMsg_445);
//	}
//
//	/**
//	 * 查询支付结果
//	 */
//	public void checkPaymentResult() {
//		List<Integer> integerList = foreignTradeRecordMapper.getInProcessTradeids();
//		if (null != integerList && integerList.size() > 0) {
//			integerList.forEach(tradeid -> {
//				try {
//					checkPaymentResult(tradeid);
//				} catch (Exception e) {
//					log.error("查询foreign平台交易支付状态报错", e);
//				}
//			});
//		} else {
//			log.info("没有查询到满足条件的交易记录！");
//		}
//	}
//
//	private void calcProjectServiceCharge(ForeignProject project, double serviceRate) {
//		BigDecimal amount = project.getAmount();
//		// 倒扣3%的比例. 这个比例根据自然人配置不同
//		BigDecimal companyDeductAmount = amount.divide(BigDecimal.valueOf(1 - serviceRate), 2, RoundingMode.DOWN);
//		BigDecimal serviceCharge = companyDeductAmount.subtract(amount);
//		project.setServiceRate(serviceRate).setServiceCharge(serviceCharge).setCompanyDeductAmount(companyDeductAmount);
//		project.updateById();
//	}
//
//	private void checkPaymentResult(int tradeid) {
//		ForeignTradeRecord trade = new ForeignTradeRecord().selectById(tradeid);
//		if (null != trade) {
//			DaysQueryAgentPayFormBean formBean = DaysQueryAgentPayFormBean.of(trade);
//			SmartResult smartResult = new RestTemplate().postForObject(zddUrlConfig.getBasePayUrl() + payConfig.getDaysQueryAgentPayUrl(), formBean, SmartResult.class);
//			if (null != smartResult && smartResult.getObject() != null && smartResult.isSuccessful()) {
//				DaysQueryPayResDTO resultDto = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), DaysQueryPayResDTO.class);
//				if (trade.getBusinessType() == Constants.KLT_PAY_BUSINESS_TYPE_USER_AMOUNT) {
//					handlePaymentTradeState(trade, resultDto.getOrderState(), resultDto.getResponseCode(), resultDto.getResponseRemark());
//				}
//			} else {
//				if (null != smartResult) {
//					LogUtil.error("查询代付结果失败！返回信息：" + smartResult.toString());
//				} else {
//					LogUtil.error("查询代付结果失败！返回信息为空！");
//				}
//			}
//		} else {
//			LogUtil.info("checkPaymentResult--->没有查询到交易记录！");
//		}
//	}
//
//	/**
//	 * 调用第三方平台的支付接口
//	 *
//	 * @param tradeRecord
//	 * @return
//	 */
//	public SmartResult doCallPayApi(ForeignTradeRecord tradeRecord) {
//		//调用第三方支付
//		// 嘉银的项目支付,都使用武圣商户号
//		RestTemplate rest = new RestTemplate();
//		DaysAgentPayFormBean formBean = DaysAgentPayFormBean.of(tradeRecord);
//		String url = zddUrlConfig.getBasePayUrl() + payConfig.getDaysAgentPayUrl();
//		LogUtil.info("支付调用 url = " + url);
//		SmartResult smartResult = rest.postForObject(url, formBean, SmartResult.class);
//		// 测试
//		// PayResultDto payResultDto = new PayResultDto("1", "", "SUCCESS", "000000", "测试支付返回。");
//		// SmartResult smartResult = SmartResult.success(payResultDto);
//		return handleDaysPayResult(tradeRecord, smartResult);
//	}
//
//	private SmartResult handleDaysPayResult(ForeignTradeRecord trade, SmartResult smartResult) {
//		if (smartResult.getObject() == null || smartResult.isFailed()) {
//			//支付失败,回滚并显示失败原因
//			String rollbackMsg = "";
//			if (smartResult.getObject() != null) {
//				DaysPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), DaysPayResDTO.class);
//				rollbackMsg = payResult.getResponseRemark();
//			} else {
//				rollbackMsg = smartResult.getMsg();
//			}
//
//			LogUtil.info("支付失败,回滚并显示失败原因");
//			throw SmartException.of(rollbackMsg);
//
//		} else {
//			//支付接口调用成功,查看交易结果
//			DaysPayResDTO payResult = JSON.parseObject(JSON.toJSONString(smartResult.getObject()), DaysPayResDTO.class);
//			trade.setPartnerOrderNo(payResult.getOrderNo()).setRequestid(payResult.getSequenceNo());
//
//			if (trade.getBusinessType() == Constants.KLT_PAY_BUSINESS_TYPE_USER_AMOUNT)
//				return handlePaymentTradeState(trade, payResult.getOrderState(), payResult.getResponseCode(), payResult.getResponseRemark());
//		}
//
//		return SmartResult.fail(StatusMsg.StatusMsg_445);
//	}
//
//	/**
//	 * 处理交易结果
//	 *
//	 * @param trade
//	 * @param orderState
//	 * @param errorcode
//	 * @param errormsg
//	 */
//	SmartResult handlePaymentTradeState(ForeignTradeRecord trade, String orderState, String errorcode, String errormsg) {
//		Asserts.notNull(trade, StatusMsg.PAYMENT_NOT_EXISTS_ERROR);
//		switch (orderState) {
//			case DaysPayOrderState.NOT_PAY:
//				trade.setTradestate(Constants.TRADE_CREATE);
//				break;
//			case DaysPayOrderState.HANDLING:
//			case DaysPayOrderState.PRIMARY_VERIFIED:
//			case DaysPayOrderState.SECONDARY_VERIFIED:
//			case DaysPayOrderState.PAYING:
//				trade.setTradestate(Constants.TRADE_IN_PROCESS);
//				break;
//			case DaysPayOrderState.PAY_SUCCESSFUL:
//				trade.setTradestate(Constants.TRADE_SUCCESS).setFinishtime(new Date());
//				break;
//			case DaysPayOrderState.PAY_FAILED:
//				trade.setTradestate(Constants.TRADE_FAIL).setFinishtime(new Date());
//				// wxMessageService.notifyAdminPaymentFail(trade);
//				break;
//			case "":
//			default:
//				trade.setTradestate(Constants.TRADE_FAIL).setFinishtime(new Date());
//				// wxMessageService.notifyAdminPaymentFail(trade);
//				break;
//		}
//		trade.setErrorcode(errorcode).setErrormsg(errormsg);
//		if (trade.updateById()) {
//			handleProjectState(trade);
//			return SmartResult.success();
//		}
//		return SmartResult.fail(StatusMsg.StatusMsg_446);
//	}
//
//	private void handleProjectState(ForeignTradeRecord trade) {
//		Integer projectId = trade.getProjectId();
//		ForeignProject project = new ForeignProject().selectById(projectId);
//		if (null != project) {
//			Integer tradestate = trade.getTradestate();
//			switch (tradestate) {
//				case Constants.TRADE_SUCCESS:
//					project.setPayState(3);
//					break;
//				case Constants.TRADE_FAIL:
//				case Constants.TRADE_REFUSE:
//					project.setPayState(4);
//					break;
//				default:
//					break;
//			}
//			project.updateById();
//		} else {
//			LogUtil.error("没有获取到项目信息！项目ID：" + projectId + ";交易流水ID：" + trade.getTradeid());
//		}
//	}
//
//	public void deductCompanyBalanceForPublishProject(CrowdsourceAccount crowdsourceAccount, CompanyAccount account, ForeignProject project) {
//		int compid = project.getCompid();
//		BigDecimal deductAmount = project.getCompanyDeductAmount();
//		//扣除余额
//		BigDecimal beforeBalance = account.getBalance();
//		BigDecimal beforeFrozenBalance = account.getFrozenBalance();
//		BigDecimal afterSubtract = account.getBalance().subtract(deductAmount);
//		if (afterSubtract.compareTo(BigDecimal.ZERO) < 0) {
//			project.setPayState(4).setMsg("账户余额不足,请充值").updateById();
//			throw SmartException.of(StatusMsg.StatusMsg_310);
//		}
//
//		account.setBalance(afterSubtract);
//		if (companyAccountMapper.updateById(account) > 0) {
//			BigDecimal currBalance = account.getBalance();
//			BigDecimal currFrozenBalance = account.getFrozenBalance();
//			// order.setState(Constants.orderstate_3).updateById();
//			//生成企业流水
//			CompanyAccountflow accountflow = new CompanyAccountflow().setCompid(compid)
//					.setFlowname(project.getProjectName() + "-项目付款给自然人-" + crowdsourceAccount.getRealname())
//					.setFlowtype(2)
//					.setBizid(project.getProjectId())
//					.setBizType(CompanyAccountFlowBizType.FOREIGN_PROJECT)
//					.setAccountType(CompanyAccountFlowAccountType.ZDD_UNIFY)
//					.setFlowAmount(deductAmount)
//					.setBeforeBalance(beforeBalance)
//					.setCurrBalance(currBalance)
//					.setBeforeFrozenBalance(beforeFrozenBalance)
//					.setCurrFrozenBalance(currFrozenBalance);
//			if (accountflow.insert()) {
//				return;
//			}
//		}
//		//如果执行到这里了,说明前面有数据库插入或更新报错,需要回滚
//		log.info("发布项目,处理扣除企业余额失败,需要回滚");
//		throw new RollbackException("发布项目失败");
//	}
//
//	/**
//	 * 定时任务, 处理新项目的支付.
//	 */
//	public void handleNewProjectPayment() {
//		foreignProjectMapper.listPendingPayProject().forEach(project -> {
//			log.info("处理外部项目支付, foreign project = {}", project.getProjectId());
//			// 手动提交事务的方式,进行外部项目支付
//			transact(() -> payProject(project));
//		});
//	}
//
//	/**
//	 * 查看外部项目支付结果 若已支付 向发票表（zdd_foreign_invoice）中刷数据
//	 */
//	public void brushForeignInvoice() {
//		foreignProjectMapper.brushForeignInvoice().forEach(project -> {
//			ForeignInvoice foreignInvoice = new ForeignInvoice();
//			foreignInvoice.setAmount(project.getAmount()).setCrowdsourceid(project.getCrowdsourceid()).setProjectId(project.getProjectId());
//			if (!foreignInvoice.insert()) {
//				LogUtil.error("新增外部项目发票记录失败!");
//			}
//			project.setInvoiceId(foreignInvoice.getId()).updateById();
//		});
//	}
//
//}
